/*
 *  Copyright (c) 2001 Sun Microsystems, Inc.  All rights
 *  reserved.
 *
 *  Redistribution and use in source and binary forms, with or withouta
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *  1. Redistributions of sourcec code must retain the above copyright
 *  notice, this list of conditions and the following disclaimer.
 *
 *  2. Redistributions in binary form must reproduce the above copyright
 *  notice, this list of conditions and the following discalimer in
 *  the documentation and/or other materials provided with the
 *  distribution.
 *
 *  3. The end-user documentation included with the redistribution,
 *  if any, must include the following acknowledgment:
 *  "This product includes software developed by the
 *  Sun Microsystems, Inc. for Project JXTA."
 *  Alternately, this acknowledgment may appear in the software itself,
 *  if and wherever such third-party acknowledgments normally appear.
 *
 *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA"
 *  must not be used to endorse or promote products derived from this
 *  software without prior written permission. For written
 *  permission, please contact Project JXTA at http://www.jxta.org.
 *
 *  5. Products derived from this software may not be called "JXTA",
 *  nor may "JXTA" appear in their name, without prior written
 *  permission of Sun.
 *
 *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 *  WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 *  DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
 *  ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
 *  USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 *  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 *  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
 *  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 *  SUCH DAMAGE.
 *  ===================================================tre=================
 *
 *  This software consists of voluntary contributions made by many
 *  individuals on behalf of Project JXTA.  For more
 *  information on Project JXTA, please see
 *  <http://www.jxta.org/>.
 *
 *
 *  $Id: SearchManager.java,v 1.3 2006/06/06 18:46:23 nano Exp $
 */
package net.jxta.myjxta.search;

import net.jxta.myjxta.MyJXTA;
import net.jxta.myjxta.util.Group;
import net.jxta.myjxta.util.objectmodel.JxtaNode;

import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

/*
 * $Id: SearchManager.java,v 1.3 2006/06/06 18:46:23 nano Exp $
 *
 * Created on October 31, 2004, 1:23 AM
 * @author james todd [gonzo at jxta dot org]
 */

public class SearchManager {

    private static final int MAX_SEARCH_TIME = 3 * 60 * 1000;
    private static final String EMPTY_STRING = "";
    private static SearchManager instance = null;

    private List<Context> searches = null;

    public static synchronized SearchManager getInstance() {
        if (instance == null) {
            instance = new SearchManager();
        }

        return (instance != null ?
                instance : (instance = new SearchManager()));
    }

    public boolean search(int context, Group group, final MyJXTA myjxta) {
        return search(context, group, myjxta, "");
    }

    public boolean search(int context, Group group, final MyJXTA myjxta,
                          String term) {
        boolean isValid = false;
        final Context c = new Context(context, group, term);

        if (! isWorking(c)) {
            final Searcher searcher = new Searcher(context, group, myjxta);
            SearchModifier modifier = new SearchModifier(SearchModifier.DEFAULT,
                    EMPTY_STRING, SearchModifier.WILDCARD);

            searcher.addListener(new AbstractSearchListener() {
                public void add(JxtaNode node) {
                    myjxta.addJxtaNode(node);
                }
            });
            searcher.start(modifier.createTerm(term));

            new Timer(true).schedule(new TimerTask() {
                public void run() {
                    searcher.stop();
                    remove(c);
                }
            }, MAX_SEARCH_TIME);

            add(c);

            isValid = true;
        }

        return isValid;
    }

    private boolean isWorking(Context c) {
        return this.searches != null ?
                this.searches.contains(c) : false;
    }

    private void add(Context c) {
        if (c != null) {
            if (this.searches == null) {
                this.searches = new ArrayList<Context>();
            }

            this.searches.add(c);
        }
    }

    private void remove(Context c) {
        if (this.searches != null) {
            this.searches.remove(c);

            if (this.searches.isEmpty()) {
                this.searches.clear();
                this.searches = null;
            }
        }
    }

    public void destoy() {
//        for (Iterator iterator = searches.iterator(); iterator.hasNext();) {
//            Context context = (Context) iterator.next();
//            context.
//        }
    }
}

class Context {
    private int context = -1;
    private Group group = null;
    private String term = null;

    public Context(int context, Group group, String term) {
        this.context = context;
        this.group = group;
        this.term = term;
    }

    public int getContext() {
        return this.context;
    }

    public Group getGroup() {
        return this.group;
    }

    public String getTerm() {
        return this.term;
    }

    public boolean equals(Object o) {
        return o instanceof Context &&
                ((Context) o).getContext() == getContext() &&
                ((Context) o).getGroup() == getGroup() &&
                ((Context) o).getTerm() != null &&
                ((Context) o).getTerm().equals(getTerm());
    }
}
